﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Web.Http;

//“空白页”项模板在 http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 上有介绍

namespace SendWns
{
    /// <summary>
    /// 可用于自身或导航至 Frame 内部的空白页。
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }


        private async void button_Tapped(object sender, TappedRoutedEventArgs e)
        {
            //var token = await GetAccessToken("n3sYaRjh44jokA+uFgVBAzjBFP6Qg+x3", "ms-app://s-1-15-2-3211818919-290936732-3790425992-3389273280-1295659862-781607565-1364420030");
            var rsp = await PostToWns("kakxJrPHr8+dIIBBcD5FtzBezpnIlB6R", "ms-app://s-1-15-2-1661610912-1515328347-2887661438-3230030922-3978289877-1935754074-3442963194"
            //var rsp = await PostToWns("zTLba87OmFz7fbfFHXuN8DOQRnfJhEVN", "ms-app://s-1-15-2-2787977642-2596187455-1933116663-3935185485-3361167551-4077010599-2189015828"
                , "https://hk2.notify.windows.com/?token=AwYAAADGifceovpP6wKQSnxAU296HFWyl2OnNDxhQsrPEqVvH%2f2vdn3VNj8R32qv6StG1809ojc5A7M6tV0%2bx6OJPA9vdl%2fVzn%2b7I2O%2bg91etQnDxMoHukv8rPwNW%2f1CBPGKvDI%3d"
                //, "https://hk2.notify.windows.com/?token=AwYAAAB27VxD%2f0NtpEkLCrsNE2PgmpMY7%2fnpGE1EB7dqKJZNvdoykPkFdY9%2fWTVpQaqxNkuCt%2b98fqVayhSJVaxsg5XnuOB5AwZ0gAfki%2bEV453rB6xtzqApegpizlSrpa7uYFE%3d"
                //, "<toast launch=\"http://tb.cn/n/ww/p?at=1\"><visual><binding template=\"ToastImageAndText02\"><image id=\"1\" src=\"image1\" alt=\"image1\" /><text id=\"1\">headlineText</text><text id=\"2\">bodyText</text></binding></visual></toast>"

                , "<toast launch=\"http://tb.cn/n/ww/p?t=0&amp;at=4&amp;id=2193061403&amp;sid=20150804162017&amp;wmc_source_id=20150804162017&amp;nav_source_id=agoo:f__-rqjvJaNnWG3l\"><visual><binding template=\"ToastImageAndText02\"><image id=\"1\" src=\"image1\" alt=\"image1\" /><text id=\"1\">headlineText</text><text id=\"2\">bodyText</text></binding></visual></toast>"
                , "wns/toast"

                //, "<badge value=\"14\"/>"
                //, "wns/badge"
                );
            string s = "";
        }

        // Post to WNS
        public async System.Threading.Tasks.Task<string> PostToWns(string secret, string sid, string uri, string xml, string notificationType)
        {

            string response = "";
            try
            {
                // You should cache this access token.
                var accessToken = await GetAccessToken(secret, sid);

                HttpClient _httpClient = new HttpClient();
                HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, new Uri(uri));
                req.Headers.Add("X-WNS-Type", notificationType);
                req.Headers.Add("Authorization", string.Format("Bearer {0}", accessToken.AccessToken));
                HttpStringContent postData = new HttpStringContent(xml, Windows.Storage.Streams.UnicodeEncoding.Utf8, "text/xml");
                req.Content = postData;

                var resp = await _httpClient.SendRequestAsync(req);
                response = await resp.Content.ReadAsStringAsync();
            }
            catch (System.Net.WebException webException)
            {
                //HttpStatusCode status = ((HttpWebResponse)webException.Response).StatusCode;

                //if (status == HttpStatusCode.Unauthorized)
                //{
                //    // The access token you presented has expired. Get a new one and then try sending
                //    // your notification again.

                //    // Because your cached access token expires after 24 hours, you can expect to get 
                //    // this response from WNS at least once a day.

                //    GetAccessToken(secret, sid);

                //    // We recommend that you implement a maximum retry policy.
                //    return PostToWns(uri, xml, secret, sid, notificationType, contentType);
                //}
                //else if (status == HttpStatusCode.Gone || status == HttpStatusCode.NotFound)
                //{
                //    // The channel URI is no longer valid.

                //    // Remove this channel from your database to prevent further attempts
                //    // to send notifications to it.

                //    // The next time that this user launches your app, request a new WNS channel.
                //    // Your app should detect that its channel has changed, which should trigger
                //    // the app to send the new channel URI to your app server.

                //    return "";
                //}
                //else if (status == HttpStatusCode.NotAcceptable)
                //{
                //    // This channel is being throttled by WNS.

                //    // Implement a retry strategy that exponentially reduces the amount of
                //    // notifications being sent in order to prevent being throttled again.

                //    // Also, consider the scenarios that are causing your notifications to be throttled. 
                //    // You will provide a richer user experience by limiting the notifications you send 
                //    // to those that add true value.

                //    return "";
                //}
                //else
                //{
                //    // WNS responded with a less common error. Log this error to assist in debugging.

                //    // You can see a full list of WNS response codes here:
                //    // http://msdn.microsoft.com/en-us/library/windows/apps/hh868245.aspx#wnsresponsecodes

                //    string[] debugOutput = {
                //                       status.ToString(),
                //                       webException.Response.Headers["X-WNS-Debug-Trace"],
                //                       webException.Response.Headers["X-WNS-Error-Description"],
                //                       webException.Response.Headers["X-WNS-Msg-ID"],
                //                       webException.Response.Headers["X-WNS-Status"]
                //                   };
                //    return string.Join(" | ", debugOutput);
                //}
            }
            catch (Exception ex)
            {
                return "EXCEPTION: " + ex.Message;
            }
            return response;
        }

        // Authorization
        [DataContract]
        public class OAuthToken
        {
            [DataMember(Name = "access_token")]
            public string AccessToken { get; set; }
            [DataMember(Name = "token_type")]
            public string TokenType { get; set; }
        }

        private OAuthToken GetOAuthTokenFromJson(string jsonString)
        {
            using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
            {
                var ser = new DataContractJsonSerializer(typeof(OAuthToken));
                var oAuthToken = (OAuthToken)ser.ReadObject(ms);
                return oAuthToken;
            }
        }

        private async System.Threading.Tasks.Task<OAuthToken> GetAccessToken(string secret, string sid)
        {
            string response = "";
            try
            {
                HttpClient _httpClient = new HttpClient();
                HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, new Uri("https://login.live.com/accesstoken.srf"));
                HttpFormUrlEncodedContent postData = new HttpFormUrlEncodedContent(
                    new List<KeyValuePair<string, string>>
                    {
                        new KeyValuePair<string, string>("grant_type", "client_credentials"),
                        new KeyValuePair<string, string>("client_id", sid),
                        new KeyValuePair<string, string>("client_secret", secret),
                        new KeyValuePair<string, string>("scope", "notify.windows.com")
                    }
                );
                req.Content = postData;

                var resp = await _httpClient.SendRequestAsync(req);
                response = await resp.Content.ReadAsStringAsync();
            }
            catch (Exception)
            {
            }
            return GetOAuthTokenFromJson(response);
        }
    }
}
